<!doctype html>
<html lang="en" class="no-js">
    <head>
        <meta charset="utf-8">

        <title>Touch event test</title>

        <meta name="viewport" content="width=device-width, initial-scale=1.0">

        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
    </head>

    <body>
        <style>

            .log{
                margin: 0;;
                height: 100px;
                width: 200px;
                float:left;
            }
            .draggable{
                /* transition:left 0.01s ease-out, top 2s ease-in;*/
            }
        </style>

        <script>
            var DragDropContainer = {
                isDragging: false,
                dragNode: null,
                dropNode: null,
                dx: 0,
                dy: 0,
                originStyle: null,
                onDrop: function() {
                    $(DragDropContainer.dropNode).before(DragDropContainer.dragNode);
                    var stringOnDropMethod = $(DragDropContainer.dropNode).attr('ondrop');
                    
                    if(stringOnDropMethod !== null && stringOnDropMethod.length>0){
                        if(stringOnDropMethod.indexOf('(')>0){
                            stringOnDropMethod = stringOnDropMethod.substr(0,stringOnDropMethod.indexOf('('));
                        }
                        var onDropMethod = window[stringOnDropMethod];
                        if(typeof onDropMethod === "function"){
                            onDropMethod.apply(null,[DragDropContainer.dragNode, DragDropContainer.dropNode]);
                        }
                        
                    }
                    
                },
                reset: function() {
                    DragDropContainer.isDragging = false;
                    DragDropContainer.dragNode = null;
                    DragDropContainer.dropNode = null;
                    DragDropContainer.dx = 0;
                    DragDropContainer.dy = 0;
                    originStyle = null;
                },
                clearDragStyle: function() {
                    if (DragDropContainer.dragNode) {
                        $(DragDropContainer.dragNode).attr('style', DragDropContainer.originStyle);
                    }
                }

            };

            function touchHandler(event) {
                var touch = event.changedTouches[0];
                var simulatedEvent = document.createEvent("MouseEvent");
                simulatedEvent.initMouseEvent({
                    touchstart: "mousedown",
                    touchmove: "mousemove",
                    touchend: "mouseup"
                }[event.type], true, true, window, 1,
                        touch.screenX, touch.screenY,
                        touch.clientX, touch.clientY, false,
                        false, false, false, 0, null);

                touch.target.dispatchEvent(simulatedEvent);
                event.preventDefault();
            }
            
            function getDroppableContainer(node){
                if(node===null){
                    return null;
                }else if($(node).hasClass('droppable')){
                    return node;
                }else{
                    return getDroppableContainer(node.parentNode);
                }
                
            }
            
            function onAction(dragNode,dropNode){
                //alert($(dragNode).html() + '::' + $(dropNode).html());
            };
            
            $(function() {

                $('.draggable').mousedown(function(e) {
                    e.preventDefault();
                    DragDropContainer.isDragging = true;
                    DragDropContainer.dragNode = $(this)[0];
                    DragDropContainer.originStyle = $(this).attr('style');
                    /*node.offsetTop;
                     var left = node.offsetLeft;*/
                    DragDropContainer.dx = e.clientX - $(this).offset().left;
                    DragDropContainer.dy = e.clientY - $(this).offset().top;                    
                });

                $('.draggable').mousemove(function(e) {
                    if (DragDropContainer.isDragging) {
                        $(DragDropContainer.dragNode).css('z-index', '9999');
                        $(DragDropContainer.dragNode).css('left', (e.clientX - DragDropContainer.dx) + 'px');
                        $(DragDropContainer.dragNode).css('top', (e.clientY - DragDropContainer.dy) + 'px');
                        $(DragDropContainer.dragNode).css('position', 'absolute');
                    }
                    e.preventDefault();

                });

                $('.draggable').mouseup(function(e) {
                    $(DragDropContainer.dragNode).css('display', 'none');
                    var tDrop = document.elementFromPoint(e.clientX, e.clientY);
                    tDrop = getDroppableContainer(tDrop);
                    if (tDrop!==null) {
                        //$(tDrop).css('background', 'yellow');
                        DragDropContainer.dropNode = tDrop;
                        DragDropContainer.dragNode.parentNode.removeChild(DragDropContainer.dragNode);
                        DragDropContainer.onDrop();
                    }
                    DragDropContainer.clearDragStyle();
                    e.preventDefault();
                });

                document.addEventListener('mouseup', function(e) {
                    e.preventDefault();
                    DragDropContainer.clearDragStyle();
                    DragDropContainer.reset();
                }, false);
                document.addEventListener("touchstart", touchHandler, true);
                 document.addEventListener("touchmove", touchHandler, true);
                 document.addEventListener("touchend", touchHandler, true);
                 document.addEventListener("touchcancel", touchHandler, true);
                /*
                 
                 */
            });
            var t=0;
        </script>
        
        <div style="background-color: aquamarine" class="log draggable droppable" >
            
            <div onmouseup="if(t>0){t=new Date().getMilliseconds() -t; alert(t);}else {t=Date().getMilliseconds();}" 
                 style="width: 50%; height: 100%;background-color: #f2f2f2">
                s
            </div>
        </div>
        <div style="background-color: #f2f2f2" ondrop="onAction(dragNode,dropNode)" class="log draggable droppable" >
            22</div>
        <div style="background-color: #f50" ondrop="onAction(dragNode,dropNode)" class="log draggable droppable" >
            33</div>
        <div style="background-color: blue" ondrop="onAction" class="log draggable droppable" >
            44</div>
        <div style="background-color: brown" ondrop="onAction" class="log draggable droppable" >
            55</div>
        <div style="background-color: yellowgreen" ondrop="onAction" class="log draggable droppable" >
            66</div>
        <div style="background-color: appworkspace" ondrop="onAction" class="log draggable droppable" >
            77</div>
        <div style="background-color: blueviolet" ondrop="onAction" class="log draggable droppable" >
            88</div>

    </body>
</html>